package demo.yml;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import demo.vo.PrometheusAlertRule;
import demo.vo.User;
import demo.vo.common.Pair;
import org.junit.Test;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.io.ByteArrayResource;
import org.yaml.snakeyaml.Yaml;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class YamlDemo {


    public static Map<String, String> alertRuleMap() {
        String s = "ruleName\talertTag\n" +
                "错误日志异常\talert_exception_count";

        List<Pair<String, String>> list = Stream.of(s.split("\n"))
                .map(l -> {
                    String[] a = l.split("\t");
                    return new Pair<String, String>(a[0], a[1]);
                })
                .collect(Collectors.toList());

        Map<String, String> map = new HashMap<>();
        for (Pair<String, String> pair : list) {
            map.put(pair.getY(), pair.getX());
        }
        return map;
    }

    /**
     * <pre>
     * name: steven
     * phone: 18********5
     * company: "******"
     * teamMember:
     *   - 于**
     *   - 徐**
     *   - 索**
     * hobbies:
     *   foods:
     *     - 黄焖鸡米饭
     *     - 黄焖排骨
     *     - 五花肉
     *     - 热干面
     *   sports:
     *     - 羽毛球
     *     - 骑车
     *     - 跑步
     *   works:
     *     - coding
     *     - repairComputer
     * working-skills:
     *   - Java
     *   - Hadoop
     *   - hive
     *   - spark
     *   - flink
     *   - kafka
     *   - HBASE
     * </pre>
     *
     * @throws FileNotFoundException
     */
    @Test
    public void demo1() throws FileNotFoundException {
        String filePath = "prom/yamlDemo.yml";
        // 1. 使用流关联yml配置文件
        BufferedReader br = new BufferedReader(new FileReader(YamlDemo.class.getClassLoader().getResource(filePath).getPath()));

        // 2. 创建yaml工具类
        Yaml yaml = new Yaml();

        // 3. 使用yaml工具类加载 流
        // 返回的字符形式非常类似于JSON, 但又不是JSON, 因为返回的字符之间使用的是 = 号连接的
        // 可以直接转换为Map 进行处理, key 的类型是 字符串, value的类型为Object
        Map<String, Object> objectMap = yaml.load(br);

        // 4. 以下就是获取yaml文件中的内容, 可以通过遍历map的方式获取, 也可以按照kv的形式获取

        // 获取所有的key
        Set<String> keySet = objectMap.keySet();
        // 通过 key 获取value
        for (String key : keySet) {
            System.out.println(key + "\t : " + objectMap.get(key).toString());
        }

        // 获取单值
        Object name = objectMap.get("name");
        System.out.println(name);

        // 获取数组类型
        ArrayList<String> teamMember = (ArrayList<String>) objectMap.get("teamMember");
        for (String member : teamMember) {
            System.out.println(member);
        }

        // 获取复合对象 , 注意类型为 LinkedHashMap
        LinkedHashMap<String, ArrayList<String>> hobbies = (LinkedHashMap<String, ArrayList<String>>) objectMap.get("hobbies");
        for (Map.Entry<String, ArrayList<String>> listEntry : hobbies.entrySet()) {
            System.out.println(listEntry.getKey() + " : " + listEntry.getValue());
        }
    }

    @Test
    public void demo2() throws FileNotFoundException {
        String filePath = "prom/alert.yml";
        // 1. 使用流关联yml配置文件
        BufferedReader br = new BufferedReader(new FileReader(YamlDemo.class.getClassLoader().getResource(filePath).getPath()));

        // 2. 创建yaml工具类
        Yaml yaml = new Yaml();

        Map<String, Object> objectMap = yaml.load(br);

        // 获取单值
        List<Object> groups = (List<Object>) objectMap.get("groups");
        System.out.println("groups.size = " + groups.size());
        groups.forEach(System.out::println);
        Map<String, String> alertRuleMap = alertRuleMap();
        for (Object group : groups) {
            Map<String, Object> group0 = (Map<String, Object>) group;

            List<Object> rules = (List<Object>) group0.get("rules");
            System.out.println("rules.size = " + rules.size());
            rules.forEach(System.out::println);
            System.out.println("-----------------------------------");
            for (Object rule : rules) {
                Map<String, Object> rule0 = (Map<String, Object>) rule;
                String alert = (String) rule0.get("alert");
                String expr = (String) rule0.get("expr");
                Map<String, Object> labels = (Map<String, Object>) rule0.get("labels");
                String service = (String) labels.get("service");
                System.err.println(alert + "," + alertRuleMap.get(alert) + "," + service + "," + expr);

            }
        }


    }

    public static String promAlertRule = """
             alert: InstanceDown
             expr: up{job="node"} == 0 and ON(instance) ping_loss_ratio{} == 1
             for: 1m
             labels:
               system: k8s_node
               service: "{{ $labels.cluster }}"
               target: "{{ $labels.instance }}"
             annotations:
               summary: "Instance Down"
               description: "{{ $labels.instance }} has been down for more than 1 minute"
               runbook_url: "http://your-wiki/runbooks/instance-down"
            """;

    @Test
    public void testPrometheusAlertRule() {
        Yaml yaml = new Yaml();
        // 解析为 Map 结构
        Map<String, Object> data = yaml.load(promAlertRule);

        System.out.println(JSON.toJSONString(data, JSONWriter.Feature.PrettyFormat));

        // 访问数据
        System.out.println("Alert: " + data.get("alert"));
        System.out.println("Expr: " + data.get("expr"));

        // 访问嵌套属性
        Map<String, Object> labels = (Map<String, Object>) data.get("labels");

        System.out.println(JSON.toJSONString(labels, JSONWriter.Feature.PrettyFormat));

        PrometheusAlertRule rule = PrometheusAlertRule.from(promAlertRule);

        System.out.println(rule);
    }

    /**
     * 将 YAML 字符串解析为 Properties（扁平化结构）
     */
    public static Properties parseToProperties(String yamlContent) {
        YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
        yamlFactory.setResources(new ByteArrayResource(yamlContent.getBytes()));
        return yamlFactory.getObject();
    }

    /**
     * 将 YAML 字符串解析为 Map（保持层次结构）
     */
    public static Map<String, Object> parseToMap(String yamlContent) {
        Yaml yaml = new Yaml();
        return yaml.load(yamlContent);
    }

    /**
     * 将 YAML 字符串解析为指定类型的对象
     */
    public static <T> T parseToObject(String yamlContent, Class<T> type) {
        Yaml yaml = new Yaml();
        return yaml.loadAs(yamlContent, type);
    }

    public static String toYaml(Object object) {
        Yaml yaml = new Yaml();
        return yaml.dump(object);
    }

    @Test
    public void testToYamlStr(){
        User user = new User();
        user.setName("stan");
        user.setAge(18);
        user.setLovers(Arrays.asList("a", "b", "c"));
        user.setInfo(Map.of("a", 1, "b", 2));

        String yamlStr = toYaml(user);
        System.out.println(yamlStr);
    }
}
